#include "s_freeRTOS_event.h"
#include "h_stm32_hal_defines.h"
#include <stdio.h>
#include <string.h>

s_freeRTOS_event_t s_freeRTOS_event_init(unsigned short event_deepth, \
						unsigned short normal_waitTime, unsigned short event_data_threshold)
{
	s_freeRTOS_event_t event_t;

	event_t.eventDeepth = event_deepth;
	event_t.eventWaitTime = normal_waitTime;
	event_t.eventDataThresholdLen = event_data_threshold;
	event_t.eventHandle = xQueueCreate(event_deepth, sizeof(s_freeRTOS_event_data));
	return event_t;
}

s_freeRTOS_event_state s_freeRTOS_event_enqueue(s_freeRTOS_event_t *event_t, \
							s_freeRTOS_event_type type, \
							unsigned char *data, unsigned short len, unsigned char para)
{
	s_freeRTOS_event_data que;
	if(len > event_t->eventDataThresholdLen) {
		return (s_freeRTOS_event_evtData_tooLong);
	}

	if(NULL == event_t->eventHandle) {
		return (s_freeRTOS_event_queue_null);
	}

	if(len != 0U) {
		que.data = (unsigned char *)H_STM32_MALLOC(sizeof(unsigned char) * len);
		if(NULL == que.data) {
			return s_freeRTOS_event_mallocfailed;
		}
		memcpy(que.data, data, len);
	} else {
		que.data = NULL;
	}
	
	que.type = type;
	que.len = len;
	que.para = para;

	xQueueSend(event_t->eventHandle, (void *)&que, (TickType_t)0);

	return s_freeRTOS_event_ok;
}

s_freeRTOS_event_state s_freeRTOS_event_enqueueFromISR(s_freeRTOS_event_t *event_t, \
							s_freeRTOS_event_type type, \
							unsigned char *data, unsigned short len, unsigned char para)
{
	s_freeRTOS_event_data que;
	BaseType_t xHigherPriorityTaskWoken= pdFALSE;

	if(len > event_t->eventDataThresholdLen) {
		return (s_freeRTOS_event_evtData_tooLong);
	}

	if(NULL == event_t->eventHandle) {
		return (s_freeRTOS_event_queue_null);
	}

	if(len != 0U) {
		que.data = (unsigned char *)H_STM32_MALLOC(sizeof(unsigned char) * len);
		if(NULL == que.data) {
			return s_freeRTOS_event_mallocfailed;
		}
		memcpy(que.data, data, len);
	} else {
		que.data = NULL;
	}
	
	que.type = type;
	que.len = len;
	que.para = para;

	xQueueSendFromISR(event_t->eventHandle, (void *)&que, \
		&xHigherPriorityTaskWoken);

	if(xHigherPriorityTaskWoken)
	{
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
	}

	return s_freeRTOS_event_ok;
}

s_freeRTOS_event_state s_freeRTOS_event_dequeue(s_freeRTOS_event_t *event_t, \
													s_freeRTOS_event_data *que)
{
	if(xQueueReceive(event_t->eventHandle, que, ( TickType_t )event_t->eventWaitTime))
	{
		return (s_freeRTOS_event_ok);
	} 
	else
	{
		return (s_freeRTOS_event_noEvent);
	}
}

s_freeRTOS_event_state s_freeRTOS_event_dequeueFromISR(s_freeRTOS_event_t *event_t, \
													s_freeRTOS_event_data *que)
{
	BaseType_t xTaskWokenByReceive = pdFALSE;

	if(xQueueReceiveFromISR(event_t->eventHandle, que, &xTaskWokenByReceive))
	{
		if(xTaskWokenByReceive != pdFALSE)
		{
			portYIELD();
		}
		return (s_freeRTOS_event_ok);
	} 
	else
	{
		return (s_freeRTOS_event_noEvent);
	}
}
